if {"::tcltest" ni [namespace children]} {
	package require tcltest
	namespace import ::tcltest::*
}

package require rl_json
package require parse_args
namespace path {::rl_json ::parse_args}

source [file join [file dirname [info script]] helpers.tcl]

test set-1.1 {Update a key in an object with a string} -setup { #<<<
	set json {
		{
			"foo": "Foo",
			"baz": "Baz"
		}
	}
} -body {
	json set json bar {"Bar"}
	compare_json {
		{
			"foo": "Foo",
			"bar": "Bar",
			"baz": "Baz"
		}
	} $json
} -cleanup {
	unset -nocomplain json
} -result match
#>>>
test set-1.2 {Update a key in an object with a number} -setup { #<<<
	set json {
		{
			"foo": "Foo",
			"bar": "Bar",
			"baz": "Baz"
		}
	}
} -body {
	json set json bar 1.6
	compare_json {
		{
			"foo": "Foo",
			"bar": 1.6,
			"baz": "Baz"
		}
	} $json
} -cleanup {
	unset -nocomplain json
} -result match
#>>>
test set-1.3 {Update a key in an object with an object} -setup { #<<<
	set json {
		{
			"foo": "Foo",
			"bar": "Bar",
			"baz": "Baz"
		}
	}
} -body {
	json set json bar {{"x":true}}
	compare_json {
		{
			"foo": "Foo",
			"bar": {
				"x": true
			},
			"baz": "Baz"
		}
	} $json
} -cleanup {
	unset -nocomplain json
} -result match
#>>>
test set-1.4 {Update a key in an object with an array} -setup { #<<<
	set json {
		{
			"foo": "Foo",
			"bar": "Bar",
			"baz": "Baz"
		}
	}
} -body {
	json set json bar {["x", 42, null, true, false]}
	compare_json {
		{
			"foo": "Foo",
			"bar": ["x", 42, null, true, false],
			"baz": "Baz"
		}
	} $json
} -cleanup {
	unset -nocomplain json
} -result match
#>>>
test set-1.5 {Update a key in an object with a null} -setup { #<<<
	set json {
		{
			"foo": "Foo",
			"bar": "Bar",
			"baz": "Baz"
		}
	}
} -body {
	json set json bar null
	compare_json {
		{
			"foo": "Foo",
			"bar": null,
			"baz": "Baz"
		}
	} $json
} -cleanup {
	unset -nocomplain json
} -result match
#>>>
test set-1.6 {Update a key in an object with a boolean: true} -setup { #<<<
	set json {
		{
			"foo": "Foo",
			"bar": "Bar",
			"baz": "Baz"
		}
	}
} -body {
	json set json bar true
	compare_json {
		{
			"foo": "Foo",
			"bar": true,
			"baz": "Baz"
		}
	} $json
} -cleanup {
	unset -nocomplain json
} -result match
#>>>
test set-1.7 {Update a key in an object with a boolean: false} -setup { #<<<
	set json {
		{
			"foo": "Foo",
			"bar": "Bar",
			"baz": "Baz"
		}
	}
} -body {
	json set json bar false
	compare_json {
		{
			"foo": "Foo",
			"bar": false,
			"baz": "Baz"
		}
	} $json
} -cleanup {
	unset -nocomplain json
} -result match
#>>>
test set-2.1 {Do Nothing Gracefully (sort of - don't blow up if an empty path is supplied} -setup { #<<<
	set json {
		{
			"foo": "Foo",
			"baz": "Baz"
		}
	}
} -body {
	json set json {"Bar"}
	compare_json {
		"Bar"
	} $json
} -cleanup {
	unset -nocomplain json
} -result match
#>>>

test set-3.1 {Create missing objects in path} -setup { #<<<
	set json {
		{
			"foo": "Foo",
			"baz": "Baz"
		}
	}
} -body {
	json set json bar Bar FooBar test {"x"}
	json set json bar Bar FooBar test2 {"y"}
	json set json bar Bar FooBar test3 {"z"}

	set json
} -cleanup {
	unset -nocomplain json
} -result {{"foo":"Foo","baz":"Baz","bar":{"Bar":{"FooBar":{"test":"x","test2":"y","test3":"z"}}}}}

#>>>
test set-3.2 {Return value of set is the new variable's value} -setup { #<<<
	set json {
		{
			"foo": "Foo",
			"baz": "Baz"
		}
	}
} -body {
	json set json foo {"Bar"}
} -cleanup {
	unset -nocomplain json
} -result {{"foo":"Bar","baz":"Baz"}}
#>>>

test set-4.1 {Create a variable if it didn't exist} -body { #<<<
	json set newvar x y z {
		{
			"foo": "Foo",
			"bar": [1, 2, 3]
		}
	}
	set newvar
} -cleanup {
	unset -nocomplain newvar
} -result {{"x":{"y":{"z":{"foo":"Foo","bar":[1,2,3]}}}}}
#>>>
test set-4.2 {Create a variable if it didn't exist with atomic type - string} -body { #<<<
	json set newvar {"foo"}
	set newvar
} -cleanup {
	unset -nocomplain newvar
} -result {"foo"}
#>>>
test set-4.3 {Create a variable if it didn't exist with atomic type - number} -body { #<<<
	json set newvar 42
	set newvar
} -cleanup {
	unset -nocomplain newvar
} -result 42
#>>>
test set-4.4 {Create a variable if it didn't exist with atomic type - null} -body { #<<<
	json set newvar null
	set newvar
} -cleanup {
	unset -nocomplain newvar
} -result null
#>>>
test set-4.5 {Create a variable if it didn't exist with atomic type - boolean: true} -body { #<<<
	json set newvar true
	set newvar
} -cleanup {
	unset -nocomplain newvar
} -result true
#>>>
test set-4.6 {Create a variable if it didn't exist with atomic type - boolean: false} -body { #<<<
	json set newvar false
	set newvar
} -cleanup {
	unset -nocomplain newvar
} -result false
#>>>
test set-4.7 {Create a variable if it didn't exist with array} -body { #<<<
	json set newvar {[1, 2, 3]}
	set newvar
} -cleanup {
	unset -nocomplain newvar
} -result {[1,2,3]}
#>>>
test set-4.8 {Create a variable if it didn't exist with object} -body { #<<<
	json set newvar {{"foo": null}}
	set newvar
} -cleanup {
	unset -nocomplain newvar
} -result {{"foo":null}}
#>>>

test set-5.1 {Set an existing element in an array, numbered} -setup { #<<<
	set json {
		{
			"foo": ["a", "b", "c"]
		}
	}
} -body {
	json set json foo 1 {"updated"}
	set json
} -cleanup {
	unset -nocomplain json
} -result {{"foo":["a","updated","c"]}}
#>>>
test set-5.2 {Prepend an element in an array, numbered} -setup { #<<<
	set json {
		{
			"foo": ["a", "b", "c"]
		}
	}
} -body {
	json set json foo -1 {"updated"}
	set json
} -cleanup {
	unset -nocomplain json
} -result {{"foo":["updated","a","b","c"]}}
#>>>
test set-5.3 {Append an element in an array, numbered, just beyond end} -setup { #<<<
	set json {
		{
			"foo": ["a", "b", "c"]
		}
	}
} -body {
	json set json foo 3 {"updated"}
	set json
} -cleanup {
	unset -nocomplain json
} -result {{"foo":["a","b","c","updated"]}}
#>>>
test set-5.4 {Append an element in an array, numbered, 2 beyond end} -setup { #<<<
	set json {
		{
			"foo": ["a", "b", "c"]
		}
	}
} -body {
	json set json foo 5 {"updated"}
	set json
} -cleanup {
	unset -nocomplain json
} -result {{"foo":["a","b","c",null,null,"updated"]}}
#>>>

test set-6.1 {Set an existing element in an array, end} -setup { #<<<
	set json {
		{
			"foo": ["a", "b", "c"]
		}
	}
} -body {
	json set json foo end {"updated"}
	set json
} -cleanup {
	unset -nocomplain json
} -result {{"foo":["a","b","updated"]}}
#>>>
test set-6.1.2 {Set a new element in an empty array, end} -body { #<<<
	set json	[json new array]
	json set json end [json new string asdf]
	set json
} -cleanup {
	unset -nocomplain json
} -result {["asdf"]}
#>>>
test set-6.2 {Prepend an element in an array, end-relative} -setup { #<<<
	set json {
		{
			"foo": ["a", "b", "c"]
		}
	}
} -body {
	json set json foo end-3 {"updated"}
	set json
} -cleanup {
	unset -nocomplain json
} -result {{"foo":["updated","a","b","c"]}}
#>>>
test set-6.3 {Append an element in an array, end-relative, just beyond end} -setup { #<<<
	set json {
		{
			"foo": ["a", "b", "c"]
		}
	}
} -body {
	json set json foo end+1 {"updated"}
	set json
} -cleanup {
	unset -nocomplain json
} -result {{"foo":["a","b","c","updated"]}}
#>>>
test set-6.4 {Append an element in an array, end-relative, 2 beyond end} -setup { #<<<
	set json {
		{
			"foo": ["a", "b", "c"]
		}
	}
} -body {
	json set json foo end+3 {"updated"}
	set json
} -cleanup {
	unset -nocomplain json
} -result {{"foo":["a","b","c",null,null,"updated"]}}
#>>>

test set-7.1 {Be lenient about the value - if it can't be interpreted as a JSON native type, convert to a JSON string} -body { #<<<
	set j	{{}}
	foreach {k v} {
		num		42
		bool	true
		null	null
		string	string
		arr		{ [1,2,3]}
		notarr	{ [1,2,3}
	} {
		json set j $k $v
	}
	set j
} -cleanup {
	unset -nocomplain j k v
} -result [json normalize {
	{
		"num":		42,
		"bool":		true,
		"null":		null,
		"string":	"string",
		"arr":		[1,2,3],
		"notarr":	" [1,2,3"
	}
}]
#>>>

::tcltest::cleanupTests
return

# vim: ft=tcl foldmethod=marker foldmarker=<<<,>>> ts=4 shiftwidth=4
